package com.easy;

import cn.hutool.core.io.FileUtil;
import org.apache.commons.lang3.time.StopWatch;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @ClassName ForkJoinTest
 * @Description TODO
 * @Author zheng
 * @Date 2022/6/16 9:31
 * @Version 1.0
 **/
public class ForkJoinTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        File dir = FileUtil.newFile("G:\\baiye\\sss\\16k");
        File[] files = dir.listFiles();
        long size = 0;
        StopWatch started = StopWatch.createStarted();
        for (File file : files) {
            size += file.length();
            TimeUnit.MILLISECONDS.sleep(50);
        }
        started.stop();
        System.out.println("File结果是:" + size);
        System.out.println("耗时：" + started.getTime(TimeUnit.MILLISECONDS));

        started = StopWatch.createStarted();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        FileForkAndJoin fileForkAndJoin = new FileForkAndJoin(Arrays.asList(files), 0, files.length - 1);
        ForkJoinTask<Long> submit = forkJoinPool.submit(fileForkAndJoin);
        System.out.println("FileForkAndJoin结果是:" + submit.get());
        System.out.println("FileForkAndJoin耗时：" + started.getTime(TimeUnit.MILLISECONDS));

    }


}

class FileForkAndJoin extends RecursiveTask<Long> {
    //切分的阈值
    private final int THRESHOLD = 10;
    /**
     * 文件列表
     */
    private  List<File> fileList;
    /**
     * 开始索引
     */
    private  int start;
    /**
     * 结束索引
     */
    private  int end;

    public FileForkAndJoin(List<File> fileList, int start, int end) {
        this.fileList = fileList;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long size = 0L;
        //10个以下不拆分，直接计算并返回结果
        if (end - start <= THRESHOLD) {
            for (int i = start; i <= end; i++) {
                size += fileList.get(i).length();
                try {
                    TimeUnit.MILLISECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return size;
        } else {
            //二分法分割任务
            int mid = (start + end) / 2;
            FileForkAndJoin left = new FileForkAndJoin(fileList, start, mid);
            FileForkAndJoin right = new FileForkAndJoin(fileList, mid + 1, end);
            //执行任务
            left.fork();
            right.fork();
            //获取执行结果
            Long leftRes = left.join();
            Long rightRes = right.join();
            size = leftRes + rightRes;
        }
        return size;
    }
}
